package com.fubowen.lepton.dao

import androidx.paging.PagingSource
import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
import androidx.room.Transaction
import androidx.room.Update
import androidx.room.Upsert
import com.fubowen.lepton.bean.BookBean
import com.fubowen.lepton.bean.BookChapterBean
import com.fubowen.lepton.ui.reader.recycler.BookCatalog
import com.fubowen.lepton.ui.reader.recycler.Bookshelf
import com.fubowen.lepton.ui.reader.recycler.BookChapter
import kotlinx.coroutines.flow.Flow

@Dao
interface BookDao {
    @Query("select * from BookBean")
    fun all(): List<BookBean>

    @Query("select a.* from BookBean a")
    fun allFlow(): Flow<List<Bookshelf>>

    @Query("select * from BookBean where Id = :id")
    fun get(id: Int): BookBean?

    @Insert
    fun set(bean: BookBean): Long

    @Insert(onConflict = OnConflictStrategy.IGNORE)
    fun setOrIgnore(bean: BookBean): Long

    @Update
    fun put(bean: BookBean)

    @Upsert
    fun setOrPut(bean: BookBean)

    @Delete
    fun del(bean: BookBean)

    @Query("DELETE FROM BookBean")
    fun clear()

    //region BookBean 类的扩展方法
    @Query("select * from BookBean where absolutePath = :absolutePath")
    fun getByAbsolutePath(absolutePath: String): BookBean?

    @Query("SELECT * FROM BookBean WHERE isReading = 1")
    fun getReadingBookFlow(): Flow<BookBean?>

    @Query("SELECT * FROM BookBean WHERE isReading = 1")
    fun getReadingBook(): BookBean?

    @Query("UPDATE BookBean SET isReading = :isReading  WHERE id = :bookId")
    fun setReadingBook(bookId: Int, isReading: Boolean)

    @Transaction
    fun changeReadingBook(bookId: Int) {
        val book = getReadingBook()
        if (book != null) {
            if (book.id != bookId) {
                setReadingBook(book.id, isReading = false)
            }
        } else {
            setReadingBook(bookId, isReading = true)
        }
    }

    @Query("UPDATE BookBean SET readingChapter = :readingChapter,readingChapterName=:name  WHERE id = :bookId")
    fun setReadingChapterOfBook(bookId: Int, readingChapter: Int, name: String)

    //endregion

    //region BookChapterBean 类的扩展方法
    @Insert(onConflict = OnConflictStrategy.IGNORE)
    fun setOrIgnoreChapter(bean: BookChapterBean)

    @Insert(onConflict = OnConflictStrategy.IGNORE)
    fun setOrIgnoreChapter(bean: List<BookChapterBean>)

    @Query("select * from BookChapterBean where bookId = :bookId order by `order`")
    fun getChapter(bookId: Int): List<BookChapter>

    @Query("select * from BookChapterBean where bookId = :bookId and id = :chapterId")
    fun getChapterById(bookId: Int, chapterId: Int): BookChapterBean?

    @Query("select * from BookChapterBean where bookId = :bookId order by `order`")
    fun getChapterFlow(bookId: Int): Flow<List<BookChapter>>

    @Query("select * from BookChapterBean where bookId = :bookId order by `order`")
    fun getCatalogFlow(bookId: Int): Flow<List<BookCatalog>>

    @Query("select * from BookChapterBean where bookId=:bookId and isReading = 1")
    fun getReadingChapter(bookId: Int): BookChapterBean?

    @Query("UPDATE BookChapterBean SET isReading = :isReading  WHERE bookId=:bookId and id = :chapterId")
    fun setReadingChapter(bookId: Int, chapterId: Int, isReading: Boolean)

    @Query("UPDATE BookChapterBean SET isReading = :isReading,position=:position  WHERE bookId=:bookId and id = :chapterId")
    fun setReadingChapter(bookId: Int, chapterId: Int, isReading: Boolean, position: Int)

    @Transaction
    fun changeReadingChapter(bookId: Int, chapterId: Int, position: Int) {
        val oldChapter = getReadingChapter(bookId)
        val newChapter = getChapterById(bookId, chapterId)
        if (oldChapter != null) {
            if (oldChapter.bookId == bookId && oldChapter.id != chapterId) {
                val next = oldChapter.order + 1
                if (chapterId == next) {
                    setReadingChapter(oldChapter.bookId, oldChapter.id, false, -1)
                } else {
                    setReadingChapter(oldChapter.bookId, oldChapter.id, false)
                }
            }
        }

        if (newChapter != null) {
            if (position > newChapter.position) {
                setReadingChapter(bookId, chapterId, true, position)
            } else {
                setReadingChapter(bookId, chapterId, true)
            }
            if (oldChapter?.bookId != bookId || oldChapter.id != chapterId) {
                setReadingChapterOfBook(newChapter.bookId, newChapter.order, newChapter.name)
            }
        }
    }

    @Query("UPDATE BookChapterBean SET content = :content,words=:words,isDownload = 1  WHERE id = :chapterId")
    fun setChapterContent(chapterId: Int, content: String, words: Int)

    @Query("select * from BookChapterBean where bookId=:bookId limit :takeCount offset :skipCount")
    fun getPageChapter(bookId: Int, takeCount: Int, skipCount: Int): List<BookChapter>

    @Query("select * from BookChapterBean where bookId=:bookId")
    fun bookChapter(bookId: Int): PagingSource<Int, BookChapter>

    //endregion
}